﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using TimeTracker.Provider;

namespace TimeTracker
{
    public partial class Form1 : Form
    {
        /// <summary>
        /// Holds System Last Input Time, initilize with current value.
        /// </summary>
        private static uint LastActivity = Program.LastInputTime;

        private Icon[] Icons = new Icon[] { 
            Properties.Resources.clock_animated_0,
            Properties.Resources.clock_animated_30,
            Properties.Resources.clock_animated_60,
            Properties.Resources.clock_animated_90,
            Properties.Resources.clock_animated_120,
            Properties.Resources.clock_animated_150,
            Properties.Resources.clock_animated_180,
            Properties.Resources.clock_animated_210,
            Properties.Resources.clock_animated_240,
            Properties.Resources.clock_animated_270,
            Properties.Resources.clock_animated_300,
            Properties.Resources.clock_animated_330
        };
        private long CurrentIconIndex = 0;

        public Form1()
        {
            InitializeComponent();

            this.notifyIcon1.ContextMenuStrip = this.contextMenuStrip1;
            this.notifyIcon1.Icon = Icons[0];
            this.notifyIcon1.Text = Properties.Resources.CurrentlyNotTracking;
            this.notifyIcon1.Visible = true;

            this.miStop.Text = Properties.Resources.Stop;

            this.BindProjects();
        }

        private void BindProjects(ToolStripMenuItem menuItem, IProject parent)
        {
            menuItem.DropDownItems.Clear();

            IEnumerable<IProject> projects = parent == null ? projects = Manager.Instance.Projects : parent.Projects;

            bool canCreateProject = Manager.Instance.CanCreateProject(parent);

            if (projects.Count() > 0)
            {
                foreach (IProject project in projects.Reverse())
                {
                    ToolStripMenuItem tempMenuItem = new ToolStripMenuItem(project.Name);
                    tempMenuItem.Tag = project;

                    tempMenuItem.DoubleClickEnabled = true;
                    tempMenuItem.DoubleClick += new EventHandler(objStartItem_Click);

                    menuItem.DropDownItems.Add(tempMenuItem);

                    this.BindProjects(tempMenuItem, project);
                }

                if (canCreateProject)
                {
                    menuItem.DropDownItems.Add(new ToolStripSeparator());
                }
            }

            if (canCreateProject)
            {
                menuItem.DropDownItems.Add(this.CreateNewProjectMenuItem());
            }
        }

        private ToolStripItem CreateNewProjectMenuItem()
        {
            TimeTracker.Controls.TerrificToolStripTextBox textBox = new Controls.TerrificToolStripTextBox();

            textBox.WatermarkText = "<new project>";
            textBox.WatermarkForeColor = Color.FromArgb(64, 64, 64);
            textBox.KeyPress += new KeyPressEventHandler(txtNewProject_KeyPress);

            return textBox;
        }

        private void BindProjects()
        {
            this.BindProjects(this.miStart, null);
            ToolStripMenuItem updateMenuItem = new ToolStripMenuItem("Update", Properties.Resources.sync);
            updateMenuItem.Click += delegate(object sender, EventArgs e) {
                this.BindProjects();
            };
            this.miStart.DropDownItems.Add(updateMenuItem);
        }

        void objStartItem_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem objItem = (ToolStripMenuItem)sender;
            IProject project = (IProject)objItem.Tag;
            this.StartTracking(project);
        }

        #region Events

        private void miExit_Click(object sender, EventArgs e)
        {
            Manager.Instance.StopTracking();

            this.notifyIcon1.Visible = false;
            this.Close();
            Application.Exit();
        }

        private void txtNewProject_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == 13)
            {
                Controls.TerrificToolStripTextBox textBox = (Controls.TerrificToolStripTextBox)sender;
                IProject parent = null;

                if (textBox.OwnerItem != null)
                {
                    parent = textBox.OwnerItem.Tag as IProject;

                    if (String.IsNullOrEmpty(textBox.Text)) { return; }

                    string name = textBox.Text;

                    this.StartTracking(parent, name);

                    if (textBox.OwnerItem is ToolStripMenuItem)
                    {
                        ToolStripMenuItem parentMenuItem = (ToolStripMenuItem)textBox.OwnerItem;

                        this.BindProjects(parentMenuItem, parent);
                    }

                }


                this.contextMenuStrip1.Hide();
            }
        }

        private void miStop_Click(object sender, EventArgs e)
        {
            this.StopTracking();
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (Manager.Instance.CurrentProject == null)
            {
                if (Manager.Instance.LastProject != null)
                {
                    this.ResumeTracking();
                }
            }
            else
            {
                this.StopTracking();
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            this.notifyIcon1.Icon = this.Icons[this.CurrentIconIndex % this.Icons.Length];
            this.CurrentIconIndex++;
        }

        private void SetNotifyIconText()
        {
            string strProjectName = Manager.Instance.CurrentProject.Name;
            string strText = String.Format(Properties.Resources.CurrentlyTracking, Manager.Instance.CurrentProject.Name, Manager.Instance.CurrentSession.Duration().TotalHours, Manager.Instance.CurrentSession.Duration().Minutes, Manager.Instance.CurrentSession.Duration().Seconds);

            if (strText.Length > 63)
            {
                int intAmountNeedToRemove = strText.Length - 63;

                strProjectName = strProjectName.Substring(0, strProjectName.Length - intAmountNeedToRemove);
                if (strProjectName.Length > 4)
                {
                    strProjectName = strProjectName.Substring(0, strProjectName.Length - 2) + "..";
                }

                strText = String.Format(Properties.Resources.CurrentlyTracking, strProjectName, Manager.Instance.CurrentSession.Duration().TotalHours, Manager.Instance.CurrentSession.Duration().Minutes, Manager.Instance.CurrentSession.Duration().Seconds);
            }

            this.notifyIcon1.Text = strText;
        }

        private void showLogToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeViewLog frmLog = TreeViewLog.Instance;

            if (!frmLog.Visible)
            {
                frmLog.ShowDialog();
            }
            frmLog.Focus();
        }

        private void txtNewNote_KeyPress(object sender, KeyPressEventArgs e)
        {
            string note = this.txtNewNote.Text;

            if (String.IsNullOrEmpty(note)) { return; }

            if (e.KeyChar == 13)
            {
                Manager.Instance.AddNote(note);

                this.contextMenuStrip1.Hide();

                this.txtNewProject.SetToDefault();

                Manager.Instance.ShowBalloonTip("Added note", note);
            }
        }


        #endregion

        private void StartTracking(IProject parent, string name)
        {
            IProject project = Manager.Instance.GetProject(parent, name);
            if (project == null)
            {
                project = Manager.Instance.CreateProject(parent, name);
            }

            this.StartTracking(project);
        }

        private void StartTracking(string name)
        {
            this.StartTracking(null, name);
        }

        private void StartTracking(IProject project)
        {
            // If we are currently tracking a project, stop tracking it first.
            if (Manager.Instance.CurrentProject != null)
            {
                Manager.Instance.StopTracking();
            }

            string name = project.Name;

            string strMessage = String.Format(Properties.Resources.StartedTracking, name);

            // Start tracking.
            Manager.Instance.StartTracking(project);

            this.miStop.Enabled = this.miStop.Visible = true;

            this.miStop.Text = String.Format(Properties.Resources.StopTrackingProject, name);

            Manager.Instance.ShowBalloonTip("Started tracking", project.FullName());
            this.StartAnimatedIcon();

            this.txtNewProject.Text = String.Empty;
            this.txtNewProject.SetToDefault();

            this.quickNote.Enabled = this.quickNote.Visible = true;

            this.SetNotifyIconText();
        }

        public void StopTracking(DateTime endTime)
        {
            if (Manager.Instance.CurrentProject == null) { return; }

            string strMessage = String.Format(Properties.Resources.StoppedTracking, Manager.Instance.CurrentProject.Name, Manager.Instance.CurrentSession.Duration().TotalHours, Manager.Instance.CurrentSession.Duration().Minutes, Manager.Instance.CurrentSession.Duration().Seconds);

            Manager.Instance.StopTracking(endTime);

            this.miStart.Enabled = this.miStart.Visible = true;
            this.miStop.Enabled = this.miStop.Visible = false;
            this.miStop.Text = Properties.Resources.Stop;

            Manager.Instance.ShowBalloonTip(strMessage);
            this.notifyIcon1.Text = Properties.Resources.CurrentlyNotTracking;
            this.StopAnimatedIcon();

            this.showLogToolStripMenuItem.Visible = Manager.Instance.GetSessionCount() > 0;

            this.quickNote.Enabled = this.quickNote.Visible = false;
        }

        public void StopTracking()
        {
            this.StopTracking(DateTime.Now);
        }

        private void ResumeTracking()
        {
            if (Manager.Instance.LastProject == null) { return; }

            this.StartTracking(Manager.Instance.LastProject);
        }

        private void StartAnimatedIcon()
        {
            timer1.Interval = (1000 / this.Icons.Length) / 2;
            timer1.Start();
        }

        private void StopAnimatedIcon()
        {
            timer1.Stop();
        }

        private void timer_IdleDetection_Tick(object sender, EventArgs e)
        {
            if (Manager.Instance.IsIdle()) { return; }

            if (Manager.Instance.CurrentProject != null)
            {
                long idleSeconds = (Environment.TickCount - Program.LastInputTime) / 1000;

                // If we have been idle more than 450 seconds (7.5 minutes) lets stop tracking the project
                if (idleSeconds > Properties.Settings.Default.IdleTimeout)
                {

                    // Display the Idle Dialog.
                    Manager.Instance.StartIdle();

                    using (IdleSession idleSession = new IdleSession())
                    {
                        idleSession.Owner = this;
                        idleSession.ShowDialog();
                    }
                }
            }

            // Attempt to free all resources
            Program.MinimizeMemory();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.Hide();
        }

        private void addNoteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            frmNote Note;

            if (Manager.Instance.CurrentProject != null)
                Note = new frmNote(Manager.Instance.CurrentProject);
            else
                Note = new frmNote();

            Note.ShowDialog();

            Note.Dispose();
        }

        private void aBoutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (AboutBox frmAboutBox = new AboutBox())
            {
                frmAboutBox.ShowDialog();
            }
        }

        private void configurationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Settings settings = new Settings();
            settings.Show();
        }

        private void idleToolStripMenuItem_Click(object sender, EventArgs e)
        {
            IdleSession idle = new IdleSession();
            idle.Owner = this;
            idle.ShowDialog();
        }
    }
}
